package src.io;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 通过提高每次实际读写的数据量减少读写的次数可以提高读写效率
 * 单字节的读写属于随机读写形式。
 * 而一组字节一组字节的读写则属于块读写形式。
 */
public class CopyDemo2 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("./movie.mp4");
        FileOutputStream fos = new FileOutputStream("./movie_cp2.mp4");

        /*
            InputStream字节输入流超类中定义了块读取操作
            int read(byte[] data)
            一次性读取给定的字节数组总长度的字节量并存入到该数组中，返回值为实际读取到的
            字节量。若返回值为-1则说明读取到了末尾。

            movie.mp4文件数据:
            11110000 10101010 00001111 11001100 00110011 11100011 00011100
            ^^^^^^^^ ^^^^^^^^ ^^^^^^^^ ^^^^^^^^

            byte[] data = new byte[4];
            int len;

            第一次调用:
            int len = fis.read(data);
            data:{11110000, 10101010, 00001111, 11001100}
            len:4 表达本次实际读取到了4个字节(data数组从第一个字节开始的前4个字节是本此读取的)


            11110000 10101010 00001111 11001100 00110011 11100011 00011100
                                                ^^^^^^^^ ^^^^^^^^ ^^^^^^^^
            第二次调用(只能读取到3个字节):
            len = fis.read(data);
            data:{00110011, 11100011, 00011100, 11001100}
                  |---------第二次读取的-------|  |-旧内容-|
            len:3 表达第二次只读取到了3个字节，意味着data前3个字节是本次读取到的内容


            11110000 10101010 00001111 11001100 00110011 11100011 00011100 文件末尾
                                                                           ^^^^^^^^
            第三次调用:
            len = fis.read(data);
            data:{00110011, 11100011, 00011100, 11001100}
                  |--------------旧内容-----------------|
            len:-1 已经读取到末尾了！本次没有读取到任何数据



            字节输出流OutputStream提供了块写数据的方法:
            void write(byte[] data)
            一次性将给定的字节数组中所有字节写出

            void write(byte[] data,int offset,int len)
            一次性将给定的字节数组从下标offset处开始的连续len个字节一次性写出
         */
        int len;
        /*
            00000000    8位2进制称为1字节  1byte
            1024byte    1kb
            1024kb      1mb  1兆
            1024mb      1gb
         */
        byte[] data = new byte[1024*10];//10kb

        long start = System.currentTimeMillis();

        while((len = fis.read(data)) != -1){
            fos.write(data,0,len);
        }

        long end = System.currentTimeMillis();
        System.out.println("复制完毕了!耗时:"+(end-start)+"毫秒");

        fis.close();
        fos.close();

    }
}
